package com.triplelink.builder.query.evalueter;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Date;

import com.triplelink.annotations.DatatypeProperty;
import com.triplelink.annotations.Property;
import com.triplelink.builder.query.QueryTL;
import com.triplelink.exception.TripleLinkException;
import com.triplelink.util.DateTimeUtil;

public class DateTimeEvalueter
{
	@SuppressWarnings("unchecked")
	public static void putValue(Field field,Object currentEntity, String id, QueryTL resources) throws IllegalArgumentException, IllegalAccessException
	{
		field.setAccessible(true);
		
		Property property = field.getAnnotation(Property.class);
		DatatypeProperty datatypeProperty = field.getAnnotation(DatatypeProperty.class);
		
		Object value = field.get(currentEntity);
		
		if (field.getType().isAssignableFrom(Date.class))
		{
			resources.appendLiteral(id, property.uri(), DateTimeUtil.parse((Date) value) , datatypeProperty);
		}
		else if (field.getType().isAssignableFrom(Collection.class))
		{
			Type type = field.getGenericType();
			
			if (type instanceof ParameterizedType && ((ParameterizedType) type).getActualTypeArguments()[0] == Date.class)
			{
				for (Date obj : (Collection<Date>) value)
					resources.appendLiteral(id, property.uri(), DateTimeUtil.parse(obj) , datatypeProperty);
			}
			else
			{
				throw new TripleLinkException(getAcceptTypeMsgException(field, property));
			}
		}
		else if (field.getType().isAssignableFrom(Date[].class))
		{
			for (Date obj : (Date[]) value)
				resources.appendLiteral(id, property.uri(), DateTimeUtil.parse(obj), datatypeProperty);
		}
		else
		{
			throw new TripleLinkException(getAcceptTypeMsgException(field, property));
		}
	}
	
	private static String getAcceptTypeMsgException(Field field, Property property)
	{
		return field + ": the property " + property.uri() + " only acepets field of Type:"
				+ " java.util.Date, Collection<java.util.Date>, java.util.Date[]";
	}
}